package logic;

import java.util.Calendar;
import java.util.concurrent.TimeUnit;
import javax.swing.JTextArea;

import io.netty.channel.ChannelInboundHandlerAdapter;
import org.apache.log4j.Logger;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.EventLoop;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;

/**
 * Created by wrs on 2019/6/3,10:03
 * projectName: Testz
 * packageName: comtest.example.admin.netty.client
 */
public class NettyClientHandler extends ChannelInboundHandlerAdapter {
    private NettyClient nettyClient;
    //private String tenantId;

    // 日志对象
    private final static Logger logger = Logger.getLogger(NettyClientHandler.class);
    // 物理检测断线后重连的间隔时间: 2秒钟
    private final int reconnectTime = 2;
    // 文本框对象
 	JTextArea sendArea;
 	// 断线重连消息
 	final String reconnctMessage = "检测到与服务端断开连接,重新连接....";
 	// 配置信息
 	private final ConfigInfo configInfo = ConfigInfo.getInstance();

    public NettyClientHandler(NettyClient nettyClient, JTextArea sendArea) {
        this.nettyClient = nettyClient;
        this.sendArea = sendArea;
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object obj) throws Exception {
    	// 收到的帧
    	String recFrame = null;
    	
    	if (configInfo.encoderStyle == 1) {
	        ByteBuf receBuf = (ByteBuf) obj;
	        byte[] recBytes = new byte[receBuf.readableBytes()];
	        receBuf.readBytes(recBytes); //将缓存区的字节数组复制到新建的req数组中
	        recFrame = Utils.bytesToHexString(recBytes);
    	} else {
    		// 字符串编解码器传输
    		recFrame = (String) obj;
    	}
    	// 判断应答帧与收到的帧是否相同
    	if (configInfo.responseFrame.equals(recFrame)) {
            logger.info("收到心跳应答：" + recFrame);
            // 记录当前时间戳
            Monitor.timestamp = Calendar.getInstance().getTimeInMillis();
            Utils.recordMsg(sendArea, "收到心跳应答帧...");
        }else{
            logger.info("收到服务端推送消息：" + recFrame);
        }
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
    	// 通道活跃
        // logger.info("output connected!");
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
    	// 日志和文本框都记录断线重连消息
        logger.info(reconnctMessage);
        Utils.recordMsg(sendArea, reconnctMessage);
        
        //使用过程中断线重连
        final EventLoop eventLoop = ctx.channel().eventLoop();
        eventLoop.schedule(new Runnable() {
            @Override
            public void run() {
                nettyClient.start();
            }
        }, reconnectTime, TimeUnit.SECONDS);
        ctx.fireChannelInactive();
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (evt instanceof IdleStateEvent) {
            IdleStateEvent event = (IdleStateEvent) evt;
            if (event.state().equals(IdleState.READER_IDLE)) {
            	// 读空闲
                // log.info("READER_IDLE");
            } else if (event.state().equals(IdleState.WRITER_IDLE)) {

            	if (configInfo.encoderStyle == 1) {
	                // 发送心跳，保持长连接
	                byte[] sByte = Utils.hexStringToBytes(configInfo.heartFrame);
	                // 发送心跳成功
	                ByteBuf byteBuf = Unpooled.wrappedBuffer(sByte);
	                ctx.channel().writeAndFlush(byteBuf);
            	} else {
            		// 字符串编解码器发送心跳
            		ctx.channel().writeAndFlush(configInfo.heartFrame);
            	}
            	logger.info("发送心跳帧: " + configInfo.heartFrame);
           	 	// 记录心跳信息
               Utils.recordMsg(sendArea, "发送心跳请求帧...");
            } else if (event.state().equals(IdleState.ALL_IDLE)) {
            	// 所有(读、写)通道(读、写)都是空闲的
                // logger.info("所有通道都是空闲...");
            }
        }
        super.userEventTriggered(ctx, evt);
    }
}
